﻿using System.ComponentModel;
using System.Windows.Media;

namespace System.Windows.Controls
{
    public class Range : INotifyPropertyChanged
    {
        private readonly bool _isLargeArc;
        private Brush _brush = new SolidColorBrush(Colors.Black);
        private string _commands = string.Empty;
        private Point _end;
        private Size _size;
        private Point _start;
        private int _thickness;

        public Range(RangeDefinition definition, Point center, double startAngle, double sweepAngle, int radius,
                     Size size)
        {
            double rangeStartAngle = startAngle - (sweepAngle*definition.Min);
            double rangeEndAngle = startAngle - (sweepAngle*definition.Max);
            Start = GetCoordinate(center, radius, rangeStartAngle);
            End = GetCoordinate(center, radius, rangeEndAngle);
            Size = size;
            Stroke = definition.Stroke;
            Thickness = definition.Thickness;
            _isLargeArc = Math.Abs(rangeEndAngle - rangeStartAngle) >= 180;
        }

        public string Commands
        {
            get
            {
                _commands = string.Format("M {0} A {1} 0 {2} 1 {3}", Start, Size, _isLargeArc ? "1" : "0", End);
                return _commands;
            }
            set
            {
                _commands = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Commands"));
            }
        }

        public Brush Stroke
        {
            get { return _brush; }
            set
            {
                _brush = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Stroke"));
            }
        }

        public int Thickness
        {
            get { return _thickness; }
            set
            {
                _thickness = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Thickness"));
            }
        }

        public Point Start
        {
            get { return _start; }
            set
            {
                _start = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Commands"));
            }
        }

        public Point End
        {
            get { return _end; }
            set
            {
                _end = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Commands"));
            }
        }

        public Size Size
        {
            get { return _size; }
            set
            {
                _size = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Commands"));
            }
        }

        public int Min { get; set; }

        public int Max { get; set; }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged = (o, e) => { };

        #endregion

        private static Point GetCoordinate(Point center, int radius, double angle)
        {
            double radians = Math.PI*angle/180;

            return new Point(center.X + radius*(float) Math.Cos(radians),
                             center.Y - radius*(float) Math.Sin(radians));
        }
    }
}